import CoinItem from "./CoinItem";
import { LanguageManager } from "./language/LanguageManager";
import RESSpriteFrame from "./RESSpriteFrame";
import Anim from "./utils/Anim";
import EffectUtils from "./utils/EffectUtils";
import MoneyChange from "./utils/MoneyChange";
import Utils from "./utils/Utils";


const { ccclass, property } = cc._decorator;

@ccclass
export default class GameUI extends cc.Component {
    @property(cc.Node)
    private clickNode1:cc.Node = null
    @property(cc.Node)
    private boxLight: cc.Node = null
    @property(cc.Node)
    private finger: cc.Node = null;
    @property(cc.Node)
    private resultNode: cc.Node = null
    @property(cc.Node)
    private maskNode: cc.Node = null
    @property(cc.Node)
    private topTitle: cc.Node = null;
    @property(cc.Prefab)
    private coinPrefab: cc.Prefab = null;
    @property(cc.Node)
    private boxNode: cc.Node = null;
    @property(cc.Node)
    private bornNode: cc.Node = null
    @property(cc.Node)
    private middlePosNode: cc.Node = null
    @property(cc.Node)
    private bottomBornNode: cc.Node = null;
    @property(cc.Node)
    private bottomMidRightNode: cc.Node = null;
    @property(cc.Node)
    private bottomMidLeftNode: cc.Node = null;
    @property(cc.Node)
    private bottomMideNode: cc.Node = null;
    @property(cc.Label)
    private moneyLabel: cc.Label = null;
    @property(cc.Label)
    private countTimeLabel: cc.Label = null
    @property(cc.Node)
    private ClickNode: cc.Node = null
    @property(cc.Node)
    private bigWinNode: cc.Node = null;
    @property(cc.Node)
    private readyGoNode: cc.Node = null;

    private isUserClick: boolean = false
    private countFunc: Function = null
    private lastFunc: Function = null;
    private isCountEnd: boolean = false
    private isFirst: boolean = true
    private allMoney: number = null;
    private CoinPool: cc.NodePool;
    private BottomPool: cc.NodePool;
    private clickTime: number = 0
    private flag: boolean = true
    private clickInterval: number = 0.2
    private lastClickTime: number = 0
    private BoxScale: number = 0.7
    private originBoxX: number = null
    private originBoxY: number = null
    private canJump: boolean = true
    private canPlayMusic: boolean = false
    private canJumpStore: boolean = true
    private canShowLight: boolean = true
    //自动点击时间间隔
    private AutoClickTime: number = null
    private canAutoForce: boolean = true
    private flyId: number = null
    protected start(): void {
        PlayerAdSdk.init();
        this.resize()
        let that = this;
        /**屏幕旋转尺寸改变 */
        cc.view.setResizeCallback(() => {
            that.resize();
        })
        cc.find('Canvas').on('touchstart', () => {
            if (!this.canPlayMusic) {
                cc.audioEngine.play(RESSpriteFrame.instance.bgmAudioClip, false, 1)
                this.canPlayMusic = true
            }
        })
        this.resize()
        //创建对象池
        this.allMoney = 0
        this.moneyLabel.node.parent.active = this.resultNode.active = this.maskNode.active = this.bigWinNode.active = this.readyGoNode.active = this.finger.active = false
        this.topTitle.active = true
        this.moneyLabel.string = `${this.allMoney}`
        this.StartCountTime()
        this.originBoxX = this.boxNode.x
        this.originBoxY = this.boxNode.y
        this.CoinPool = new cc.NodePool()
        this.BottomPool = new cc.NodePool()
        for (let i = 0; i < 1000; i++) {
            let coinItem = cc.instantiate(this.coinPrefab)
            this.CoinPool.put(coinItem)
            let bottomItem = cc.instantiate(this.coinPrefab)
            this.BottomPool.put(bottomItem)
        }
        this.clickNode1.on(cc.Node.EventType.TOUCH_START, this.createCoin, this)
        this.clickNode1.on(cc.Node.EventType.TOUCH_END, this.setScale, this)
        this.lastFunc = async () => {
            this.AutoClickTime -= this.clickInterval
            if (this.AutoClickTime <= this.clickInterval && this.canAutoForce) {
                this.unschedule(this.lastFunc)
                this.allMoney = 299
                this.createCoin(false)
            }
        }
    }
    private setScale() {
        this.ClickNode.setScale(cc.v2(1, 1))
    }
    private StartCountTime() {
        let time = 4
        this.countFunc = async () => {
            if (time <= 4) {
                this.finger.active = true
                this.topTitle.active = false
                this.countTimeLabel.node.parent.active = true
            }
            time--
            if (time <= 0) {
                this.unschedule(this.countFunc)
                this.AutoClickTime = 8
                this.schedule(this.lastFunc, 0.2)
                this.isCountEnd = true
                this.countTimeLabel.node.parent.active = this.topTitle.active = false
                this.moneyLabel.node.parent.active = true
            } else {
                this.countTimeLabel.string = `${time}`
                this.canPlayMusic && cc.audioEngine.play(RESSpriteFrame.instance.countTimeAudioClip, false, 1)
                if (time == 1) {
                    this.readyGoNode.active = true
                    // this.schedule(this.lastFunc,0.2)
                    this.canPlayMusic && cc.audioEngine.play(RESSpriteFrame.instance.readyAudioClip, false, 1)
                }
            }
        }
        this.schedule(this.countFunc, 1)
    }
    private getRandomInt(min: number, max: number) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
    private createCoin(force: boolean) {
        this.ClickNode.setScale(cc.v2(1.1, 1.1))
        this.canPlayMusic && cc.audioEngine.play(RESSpriteFrame.instance.clickAudioClip, false, 1)
        if (!this.isUserClick) {
            this.unschedule(this.lastFunc)
            this.AutoClickTime = 6
            this.schedule(this.lastFunc, 0.2)
        }
        this.isUserClick = true
        this.finger.active = false
        let currentTime = Date.now()
        this.topTitle.active = false
        // if(this.lastClickTime == 0)this.schedule(this.lastFunc,0.2)
        if (currentTime - this.lastClickTime < this.clickInterval * 1000 || this.allMoney >= 300) {
            return;
        }
        this.lastClickTime = currentTime
        if (!this.flag) return
        this.flag = false
        let flyTime = !force ? 700 : 1100
        setTimeout(() => {
            if(this.canPlayMusic){
                this.flyId = cc.audioEngine.play(RESSpriteFrame.instance.coinFlyAudioClip, false, 6)
            }
        }, flyTime);
        if (!this.isCountEnd) {  //倒计时未结束点击跳转
            this.schedule(this.countFunc, 1)
            this.unschedule(this.countFunc)
            this.moneyLabel.node.parent.active = true
            this.countTimeLabel.node.parent.active = false
        }
        if (this.isFirst) {
            this.boxNode.getComponent(cc.Animation).play('box')
            this.isFirst = false
        }
        this.clickTime++
        let coinNum = 13
        if (!force) {
            coinNum = 500
        }
        for (let i = 0; i < coinNum; i++) {
            let targetPos: cc.Vec2 = this.boxNode.parent.convertToWorldSpaceAR(cc.v2(this.boxNode.x, this.boxNode.y))
            let middlePos: cc.Vec2 = this.middlePosNode.parent.convertToWorldSpaceAR(cc.v2(this.middlePosNode.x + this.getRandomInt(0, 200), this.middlePosNode.y + this.getRandomInt(0, 200)))
            let coinItem = null
            if (this.CoinPool.size() > 0) {
                coinItem = this.CoinPool.get()
            } else {
                coinItem = cc.instantiate(this.coinPrefab)
            }
            coinItem.parent = this.bornNode
            coinItem.getComponent(CoinItem).initItem(false)
            let CoinNode = coinItem.getComponent(CoinItem).node
            let statrPos: cc.Vec2 = cc.v2(CoinNode.x + this.getRandomInt(0, 100), CoinNode.y + this.getRandomInt(0, 100))
            targetPos = CoinNode.parent.convertToNodeSpaceAR(targetPos)
            middlePos = CoinNode.parent.convertToNodeSpaceAR(middlePos)
            let time = this.getRandomInt(12, 25) * 0.1
            let randomScale = this.getRandomInt(3, 10) * 0.1
            let StartscaleTime = this.clickTime >= 3 ? 700 : 1200
            let scaleDuation = this.clickTime >= 3 ? 1.4 : 1.1
            setTimeout(() => {
                if (i == 1) {
                    cc.tween(this.boxNode)
                        .to(0.12, { x: this.originBoxX + 5, y: this.originBoxY + 25 })
                        .to(0.12, { x: this.originBoxX - 5, y: this.originBoxY - 5 })
                        .to(0.12, { x: this.originBoxX, y: this.originBoxY + 16 })
                        .to(0.12, { x: this.originBoxX + 5, y: this.originBoxY + 25 })
                        .to(0.12, { x: this.originBoxX - 5, y: this.originBoxY - 5 })
                        .to(0.12, { x: this.originBoxX, y: this.originBoxY + 16 })
                        .to(0.12, { x: this.originBoxX + 5, y: this.originBoxY + 25 })
                        .to(0.12, { x: this.originBoxX - 5, y: this.originBoxY - 5 })
                        .to(0.12, { x: this.originBoxX, y: this.originBoxY + 16 })
                        .start()
                    let randomNum = this.getRandomInt(2, 4) * 0.01
                    this.BoxScale += randomNum
                    if (this.BoxScale >= 1.1) this.BoxScale = 1.05
                    this.boxNode.runAction(cc.scaleTo(scaleDuation, this.BoxScale))
                }
            }, StartscaleTime);
            if (this.allMoney >= 265) {
                time = this.getRandomInt(9, 17) * 0.1
                if (this.allMoney >= 290) {
                    time = this.getRandomInt(6, 15) * 0.1
                }
            }
            if (!force) {
                time = this.getRandomInt(6, 20) * 0.1
            }
            let sequence = cc.sequence(cc.scaleTo(time / 3 * 2, randomScale * 1.5), cc.scaleTo(time / 3, randomScale))
            let spawn = cc.spawn(cc.bezierTo(time, [statrPos, middlePos, targetPos]), cc.rotateTo(time, 180), cc.scaleTo(time, this.getRandomInt(3, 10) * 0.1), cc.callFunc(() => {
                if (i == 1 && this.allMoney >= 300 && this.canShowLight) {
                    this.canAutoForce
                    this.canShowLight = false
                    this.boxLight.active = true
                    this.boxLight.getComponent(cc.Animation).play('boxlight')
                }
                setTimeout(() => {
                    this.CoinPool.put(coinItem)
                    if (!force) {
                        if (i == 499) {
                            setTimeout(() => {
                                this.canPlayMusic && cc.audioEngine.pause(this.flyId)
                            }, 1000);
                        }
                    } else {
                        setTimeout(() => {
                            if (i == 12) {
                                this.canPlayMusic && cc.audioEngine.pause(this.flyId)
                            }
                        }, 800);
                    }
                    if (i == 10 && this.allMoney >= 300 && this.canJump) {
                        this.canJump = false
                        this.unschedule(this.lastFunc)
                        Utils.showUI(this.bigWinNode, RESSpriteFrame.instance.bigWinAudioClip, 1.2,this.canPlayMusic,() => {
                            cc.audioEngine.pauseAll()
                            this.moneyLabel.node.parent.active = false
                            this.canPlayMusic && cc.audioEngine.play(RESSpriteFrame.instance.bgmAudioClip,false,1)
                            this.gameEnd()
                        })
                    }
                }, time * 1000);
            }))
            CoinNode.runAction(spawn)
            CoinNode.runAction(sequence)

        }
        if (this.clickTime >= 3) {
            for (let i = 0; i < 18; i++) {
                let BottomTargetPos: cc.Vec2 = this.boxNode.parent.convertToWorldSpaceAR(cc.v2(this.boxNode.x, this.boxNode.y))
                let bottomItem = null
                if (this.BottomPool.size() > 0) {
                    bottomItem = this.BottomPool.get()
                } else {
                    bottomItem = cc.instantiate(this.coinPrefab)
                }
                bottomItem.parent = this.bottomBornNode
                bottomItem.getComponent(CoinItem).initItem(true)
                let bottomCoinNode = bottomItem.getComponent(CoinItem).node
                let bottomStartPos: cc.Vec2 = cc.v2(bottomCoinNode.x, bottomCoinNode.y)
                BottomTargetPos = bottomCoinNode.parent.convertToNodeSpaceAR(BottomTargetPos)
                let time = this.getRandomInt(8, 15) * 0.1
                let midPos: cc.Vec2
                if (bottomCoinNode.x < -30) {
                    midPos = this.bottomMidLeftNode.parent.convertToWorldSpaceAR(cc.v2(this.bottomMidLeftNode.x, this.bottomMidLeftNode.y))
                } else if (bottomCoinNode.x > 30) {
                    midPos = this.bottomMidRightNode.parent.convertToWorldSpaceAR(cc.v2(this.bottomMidRightNode.x, this.bottomMidRightNode.y))
                } else {
                    midPos = this.bottomMideNode.parent.convertToWorldSpaceAR(cc.v2(this.bottomMideNode.x, this.bottomMideNode.y))
                }
                midPos = bottomCoinNode.parent.convertToNodeSpaceAR(midPos)
                let spawn1 = cc.spawn(cc.bezierTo(time, [bottomStartPos, midPos, BottomTargetPos]), cc.rotateTo(time, 180), cc.scaleTo(time, this.getRandomInt(6, 15) * 0.1), cc.callFunc(() => {
                    setTimeout(() => {
                        this.isCountEnd = true
                        this.BottomPool.put(bottomItem)
                    }, time * 1000)
                }))
                bottomCoinNode.runAction(spawn1)
            }
        }
        this.allMoney += this.getRandomInt(10, 30)
        if (this.allMoney >= 300) this.allMoney = 300
        this.moneyLabel.string = `${this.allMoney}`
        this.moneyLabel.node.getComponent(cc.Animation).play('LabelAnim')
        this.flag = true
    }
    private resize() {
        const canvasValue: any = cc.Canvas.instance;
        let frameSize = cc.view.getFrameSize();
        let isVerTical = cc.winSize.height > cc.winSize.width
        if (isVerTical) {//竖屏
            if (cc.winSize.width / cc.winSize.height > 0.7) {
                cc.Canvas.instance.fitHeight = true;
                cc.Canvas.instance.fitWidth = false;
            } else {
                cc.Canvas.instance.fitHeight = false;
                cc.Canvas.instance.fitWidth = true;
            }
        } else {
            cc.Canvas.instance.fitHeight = true;
            cc.Canvas.instance.fitWidth = false;
        }
        cc.director.getScene().getComponentsInChildren(cc.Widget).forEach(function (t) {
            t.updateAlignment()
        });
    }
    private gameEnd() {
        setTimeout(() => {
            Utils.showUI(this.resultNode, RESSpriteFrame.instance.comeOutAudioClip,0.2,this.canPlayMusic)
            this.canPlayMusic && cc.audioEngine.play(RESSpriteFrame.instance.cherrUpAudioClip, false, 1)
            this.canPlayMusic && cc.audioEngine.play(RESSpriteFrame.instance.fullScreenCoinAudioClip, false, 1)
            this.maskNode.active = this.topTitle.active = true
        }, 200);
        // setTimeout(() => {
        //     if (this.canJumpStore) this.jumpStore()
        // }, 6000);
    }
    private jumpStore() {
        this.canJumpStore = false
        console.log('跳转');
        this.canPlayMusic && cc.audioEngine.play(RESSpriteFrame.instance.clickAudioClip, false, 1)
        PlayerAdSdk.gameEnd()
        PlayerAdSdk.jumpStore()
    }
    protected onDisable(): void {

    }
    public bezierTo(target: any, duration: number, p1: cc.Vec3, cp: cc.Vec3, p2: cc.Vec3, opts?: any): cc.Tween<any> {
        opts = opts || Object.create(null);
        let twoBezier = (t: number, p1: cc.Vec3, cp: cc.Vec3, p2: cc.Vec3) => {
            let x = (1 - t) * (1 - t) * p1.x + 2 * t * (1 - t) * cp.x + t * t * p2.x;
            let y = (1 - t) * (1 - t) * p1.y + 2 * t * (1 - t) * cp.y + t * t * p2.y;
            let z = (1 - t) * (1 - t) * p1.z + 2 * t * (1 - t) * cp.z + t * t * p2.z;
            return new cc.Vec3(x, y, z);
        };
        opts.onUpdate = (_arg: cc.Vec3, ratio: number) => {
            let newPos = twoBezier(ratio, p1, cp, p2);
            target.worldPosition = newPos;
        };
        return cc.tween(target).to(duration, {}, opts);
    }
}   
